package org.sfx.diagnostics

import javafx.animation.Timeline
import javafx.animation.KeyFrame
import javafx.animation.KeyValue
import javafx.event.EventHandler
import javafx.event.ActionEvent
import javafx.scene.input.MouseEvent
import javafx.scene.shape.Rectangle
import javafx.scene.Scene
import javafx.util.Duration
import org.sfx.rich.Enrich._
import org.sfx.geometry.Bounds2D
import javafx.animation.Interpolator
import scala.collection.JavaConverters._
import org.sfx.animation.SfxTimeline

class SpyRectangle extends Rectangle {
  var timeline = new SfxTimeline()
  var spyScopeGlass: SpyScopeGlass = null
  this.setStyle(
      "-fx-fill: rgb(0%,100%,0%,0.1);" +
      "-fx-stroke: green;" +
      "-fx-stroke-width: 2;" +
      "-fx-stroke-line-cap: butt;" +
      "-fx-effect: dropshadow(gaussian, black, 5.0, 0.1, 3.0, 3.0);")
      
  def forwardMouseEventsTo(scene: Scene): Unit = {
    this.setOnMousePressed { mouseEvent: MouseEvent =>
      scene.impl_processMouseEvent(mouseEvent)
    }
    this.setOnMouseReleased { mouseEvent: MouseEvent =>
      scene.impl_processMouseEvent(mouseEvent)
    }
  }
  
  def appear(spyScopeGlass: SpyScopeGlass, target: Bounds2D): Unit = {
    val timeline = new SfxTimeline()
    var source = target.inflate(5.0)
    timeline.addTransition(Duration.seconds(0.5)) { transition =>
      SpyRectangle.this.layoutBounds = (target - source) * transition + source
      SpyRectangle.this.setOpacity(transition)
    }
    if (this.timeline != null) {
      this.timeline.jumpTo("end")
    }
    
    timeline.play()
    this.timeline = timeline
  }

  def disappear(spyScopeGlass: SpyScopeGlass, source: Bounds2D): Unit = {
    val timeline = new SfxTimeline()
    var target = source.inflate(5.0)
    timeline.addTransition(Duration.seconds(0.5)) { transition =>
      SpyRectangle.this.layoutBounds = (target - source) * transition + source
      SpyRectangle.this.setOpacity(1.0 - transition)
    }
    timeline.onFinished {
      spyScopeGlass.screenGroup.getChildren().remove(SpyRectangle.this)
    }
    if (this.timeline != null) {
      this.timeline.jumpTo("end")
    }
    timeline.play()
    this.timeline = timeline
  }
  
  def move(spyScopeGlass: SpyScopeGlass, source: Bounds2D, target: Bounds2D): Unit = {
    this.spyScopeGlass = spyScopeGlass
    if (!spyScopeGlass.isShowing()) {
      spyScopeGlass.show()
    }
    val x = spyScopeGlass.screenGroup.getChildren().addDistinct(this)
    val timeline = new SfxTimeline()
    timeline.addTransition(Duration.seconds(0.5)) { transition =>
      SpyRectangle.this.layoutBounds = (target - source) * transition + source
    }
    if (this.timeline != null) {
      this.timeline.jumpTo("end")
    }
    timeline.play()
    this.timeline = timeline
  }
}
